package com.liziguo.lzgfp.system.util;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.util.Base64;

/**
 * @Author: Liziguo
 * @Date: 2020/6/16 18:35
 */
public class AESUtil {

    //	public static final String TRANSFORMATION = "AES/ECB/NoPadding";
//	public static final String TRANSFORMATION = "AES/ECB/PKCS5Padding";
    public static final String TRANSFORMATION = "AES/CBC/PKCS5Padding";
    public static final byte[] IV = "gBz8gGMN8Hx1Wyj5".getBytes();
    public static final int KEY_SIZE = 256;//128 192 256

    public static final Charset CHARSET = StandardCharsets.UTF_8;

    public static byte[] encrypt(byte[] plaintext, byte[] key) throws Exception {
        final KeyGenerator kg = KeyGenerator.getInstance("AES");
        final SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
        secureRandom.setSeed(key);
        kg.init(KEY_SIZE, secureRandom);//192 256
        final SecretKey secretKey = kg.generateKey();
//		final SecretKeySpec secretKey = new SecretKeySpec(keyBytes, AES);
        final Cipher cipher = Cipher.getInstance(TRANSFORMATION);
        final IvParameterSpec iv = new IvParameterSpec(IV);
        cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv);
        return cipher.doFinal(plaintext);
    }

    public static byte[] encrypt(byte[] plaintext, String key) throws Exception {
        return encrypt(plaintext, key.getBytes(CHARSET));
    }

    /**
     * @param plaintext 明文
     * @param key       密钥
     * @return Base64编码
     * @throws Exception
     */
    public static byte[] encrypt(final String plaintext, final String key) throws Exception {
        return encrypt(plaintext.getBytes(CHARSET), key.getBytes(CHARSET));
    }

    public static String encryptToString(byte[] plaintext, byte[] key) throws Exception {
        return Base64.getEncoder().encodeToString(encrypt(plaintext, key));
    }

    public static String encryptToString(byte[] plaintext, String key) throws Exception {
        return Base64.getEncoder().encodeToString(encrypt(plaintext, key));
    }

    public static String encryptToString(String plaintext, String key) throws Exception {
        return Base64.getEncoder().encodeToString(encrypt(plaintext, key));
    }

    public static byte[] decrypt(byte[] ciphertext, byte[] key) throws Exception {
        final KeyGenerator kg = KeyGenerator.getInstance("AES");
        final SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
        secureRandom.setSeed(key);
        kg.init(KEY_SIZE, secureRandom);
        final SecretKey secretKey = kg.generateKey();
//		final SecretKeySpec secretKey = new SecretKeySpec(keyBytes, AES);
        //创建密码器
        final Cipher cipher = Cipher.getInstance(TRANSFORMATION);
        //偏移量
        final IvParameterSpec iv = new IvParameterSpec(IV);
        //初始化为解密模式的密码器
        cipher.init(Cipher.DECRYPT_MODE, secretKey, iv);
        return cipher.doFinal(ciphertext);
    }

    public static byte[] decrypt(byte[] ciphertext, String key) throws Exception {
        return decrypt(ciphertext, key.getBytes(CHARSET));
    }

    public static byte[] decrypt(String base64Ciphertext, String key) throws Exception {
        return decrypt(Base64.getDecoder().decode(base64Ciphertext), key.getBytes(CHARSET));
    }

    public static String decryptToString(byte[] ciphertext, byte[] key) throws Exception {
        return new String(decrypt(ciphertext, key), CHARSET);
    }

    public static String decryptToString(byte[] ciphertext, String key) throws Exception {
        return new String(decrypt(ciphertext, key), CHARSET);
    }

    public static String decryptToString(String base64Ciphertext, String key) throws Exception {
        return new String(decrypt(base64Ciphertext, key), CHARSET);
    }

    public static void main(String[] args) throws Exception {
        String key = "过得很好";
        String s = encryptToString("uii9jiubuy7hu不会用户", key);
        System.out.println(s);
        System.out.println(decryptToString(s, key));
    }

}
